package hotdeploy;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FilenameUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StopWatch;

public class HotDeploy {
	
	public static void main(String[] args) throws Exception {
		String PROJECT_PATH =System.getProperty("user.dir");	
		String projectName = "weborder";
		final String sourcepath = FilenameUtils.concat(PROJECT_PATH,"src/main/webapp"); 
		final String targetPath = FilenameUtils.concat(PROJECT_PATH,"target/"+projectName);
		final File source = new File(PROJECT_PATH,"src/main/webapp");
		
		final String classsourcepath = FilenameUtils.concat(PROJECT_PATH,"target/classes"); 
		final String classtargetpath = FilenameUtils.concat(PROJECT_PATH,"target/"+projectName+"/WEB-INF/classes");
		final File classsource = new File(PROJECT_PATH,"target/classes"); 
		final Map<String,Long> fileMap = new LinkedHashMap<String,Long>(); 
		final Map<String,Long> classMap = new LinkedHashMap<String,Long>(); 
		StopWatch watch = new StopWatch();
		while (true){
			watch.start();
		goThrough(source, new FileFilterAdaptor(), new IFileOperator(){

			@Override
			public void execute(File file) throws IOException {
				String path = file.getAbsolutePath();
				long currentModified = file.lastModified();
				if (fileMap.containsKey(path)){
					long lastModified = fileMap.get(path);
					if (lastModified+500<currentModified){
						copyFile(sourcepath,targetPath,file);
						fileMap.put(path, file.lastModified());
					}
				}else{
					fileMap.put(path, file.lastModified());
					copyFile(sourcepath,targetPath,file);
				}
			}
		});
		goThrough(classsource, new FileFilterAdaptor(), new IFileOperator(){
			
			@Override
			public void execute(File file) throws IOException {
				String path = file.getAbsolutePath();
				long currentModified = file.lastModified();
				if (classMap.containsKey(path)){
					long lastModified = classMap.get(path);
					if (lastModified+500<currentModified){
						copyFile(classsourcepath,classtargetpath,file);
						classMap.put(path, file.lastModified());
					}
				}else{
					classMap.put(path, file.lastModified());
					copyFile(classsourcepath,classtargetpath,file);
				}
			}
		});
		watch.stop();
		TimeUnit.SECONDS.sleep(5);
		
		}
	}
	
	private static void copyFile(String sourcepath, String targetPath, File file) throws IOException {
		String filepath = file.getAbsolutePath();
		String fileName = filepath.replace(sourcepath, "");
		File destFile = new File(targetPath,fileName);
		File parent = destFile.getParentFile();
		if (!parent.exists()){
			parent.mkdirs();
		}
		FileCopyUtils.copy(file, destFile);
		System.out.println("update file "+fileName);
	}
	
	public static void goThrough(File file, IFileFilter filter,
			IFileOperator operator) throws Exception {
		if (file == null || !file.exists()) {
			return;
		}
		if (file.isFile() && file.canRead() && file.canWrite()
				&& file.canExecute()) {
			if (filter == null || filter.accept(file.getName())) {
				if (operator != null) {
					operator.execute(file);
				}
			}
		} else if (file.isDirectory() && file.canRead()) {
			File[] files = file.listFiles();
			for (File child : files) {
				goThrough(child, filter, operator);
			}
		}
	}
	
}
